package com.study.lxy.threadstate;

import org.junit.Test;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadStateTest {

    @Test
    public void test1() throws Exception{

        Object lock1 = new Object();
        // 测试线程的状态 - waiting
        /**
         * "Thread-0" #12 prio=5 os_prio=0 tid=0x000000001fa42800 nid=0x19c34 in Object.wait() [0x000000002019e000]
         *    java.lang.Thread.State: WAITING (on object monitor)
         *         at java.lang.Object.wait(Native Method)
         *         - waiting on <0x000000076e9aae38> (a java.lang.Object)
         *         at java.lang.Object.wait(Object.java:502)
         *         at com.study.lxy.threadstate.ThreadStateTest.lambda$test1$0(ThreadStateTest.java:20)
         *         - locked <0x000000076e9aae38> (a java.lang.Object)
         */
        Thread t1 = new Thread(() ->{
            try {
                synchronized (lock1) {
                    System.out.println("waiting Thread");
                    lock1.wait();
                }
            } catch (Exception e){
                e.printStackTrace();
            }
        });

        // 测试线程的状态 time waiting
        /**
         * "Thread-1" #13 prio=5 os_prio=0 tid=0x000000001fa47800 nid=0x183fc waiting on condition [0x000000002029e000]
         *    java.lang.Thread.State: TIMED_WAITING (sleeping)
         *         at java.lang.Thread.sleep(Native Method)
         *         at com.study.lxy.threadstate.ThreadStateTest.lambda$test1$1(ThreadStateTest.java:33)
         *         - locked <0x000000076e9aae38> (a java.lang.Object)
         */
        Thread t2 = new Thread(() -> {
            try {
                Thread.sleep(100);
                synchronized (lock1) {
                    System.out.println("time waiting Thread");
                    Thread.sleep(100000);
                }
            } catch (Exception e){
                e.printStackTrace();
            }
        });

        // 测试线程的状态 blocked
        // synchronized 获取锁状态
        //"Thread-2" #14 prio=5 os_prio=0 tid=0x000000001fa48800 nid=0x19d64 waiting for monitor entry [0x000000002039f000]
        //java.lang.Thread.State: BLOCKED (on object monitor)
        //at com.study.lxy.threadstate.ThreadStateTest.lambda$test1$2(ThreadStateTest.java:45)
        //- waiting to lock <0x000000076e9aae38> (a java.lang.Object)
        Thread t3 = new Thread(() -> {
            try {
                Thread.sleep(500);
                synchronized (lock1) {
                    System.out.println("a block Thread");
                }
            } catch (Exception e){
                e.printStackTrace();
            }
        });

        /**
         * "Thread-3" #15 prio=5 os_prio=0 tid=0x000000001fa25000 nid=0x17130 waiting on condition [0x000000002049f000]
         *    java.lang.Thread.State: TIMED_WAITING (sleeping)
         *         at java.lang.Thread.sleep(Native Method)
         *         at com.study.lxy.threadstate.ThreadStateTest.lambda$test1$3(ThreadStateTest.java:58)
         *         at com.study.lxy.threadstate.ThreadStateTest$$Lambda$4/305623748.run(Unknown Source)
         *         at java.lang.Thread.run(Thread.java:748)
         *
         *    Locked ownable synchronizers:
         *         - <0x000000076eb7d368> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
         */
        ReentrantLock lock = new ReentrantLock();
        Thread t4 = new Thread(() -> {
           lock.lock();
            try {
                System.out.println("thread lock");
                Thread.sleep(100000);
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        // 测试使用Lock的时候，锁的状态是什么
        // 经过验证，是处于waiting状态，调用Unsafe.park()方法后，处于waiting状态
        /**
         * "Thread-4" #16 prio=5 os_prio=0 tid=0x000000001fa25800 nid=0x17b80 waiting on condition [0x000000002059e000]
         *    java.lang.Thread.State: WAITING (parking)
         *         at sun.misc.Unsafe.park(Native Method)
         *         - parking to wait for  <0x000000076eb7d368> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
         *         at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
         */
        Thread t5 = new Thread(() -> {
            lock.lock();
            try {
                System.out.println("thread lock2");
                Thread.sleep(100000);
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();

        t1.join();
        t2.join();
        t3.join();
        t4.join();
        t5.join();

    }

}
